package com.lxy.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.TypeReference;
import com.lxy.model.InvokeRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

/**
 * 统一调用接口
 */
@RequestMapping("/call")
@RestController
public class CallController {

    @Autowired
    private ApplicationContext applicationContext;

    private static final String PACKAGE_NAME = "com.lxy.controller.";

    //"{'age':18,'name':'lxy','sex':'man'}" 只能传json字符串
    //{"age":18,"name":"lxy","sex":"man"} 不能传对象，除非，在判定类型那块多写几个。传json字符串的话就不需要管他啥类型参数了
    // 统一入口
    @PostMapping("/invoke")
    public ResponseEntity<?> invokeMethod(@RequestBody InvokeRequest request) throws Exception {
        String className = PACKAGE_NAME + request.getClassName();
        String methodName = request.getMethodName();
        Map<String, Object> params = request.getParams();

        // 获取目标类
        Class<?> targetClass = Class.forName(className);

        // 获取所有方法
        Method[] methods = targetClass.getDeclaredMethods();
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                // 创建实例（也可以从 Spring 容器中获取 bean）
                Object bean = applicationContext.getBean(targetClass);

                // 构造参数数组
                Class<?>[] paramTypes = method.getParameterTypes();
                Object[] args = new Object[paramTypes.length];

                for (int i = 0; i < paramTypes.length; i++) {
                    String paramName = "arg" + i;
                    Object value = params.get(paramName);

                    if (value == null && !paramTypes[i].isPrimitive()) {
                        args[i] = null;
                    } else if (paramTypes[i] == String.class) {
                        args[i] = value.toString();
                    } else if (paramTypes[i] == int.class || paramTypes[i] == Integer.class) {
                        args[i] = Integer.parseInt(value.toString());
                    } else if (paramTypes[i] == boolean.class || paramTypes[i] == Boolean.class) {
                        args[i] = Boolean.parseBoolean(value.toString());
                    } else if (paramTypes[i] == Long.class || paramTypes[i] == long.class) {
                        args[i] = Long.parseLong(value.toString());
                    } else if (paramTypes[i] == double.class || paramTypes[i] == Double.class) {
                        args[i] = Double.parseDouble(value.toString());
                    } else if (paramTypes[i] == float.class || paramTypes[i] == Float.class) {
                        args[i] = Float.parseFloat(value.toString());
                    } else if (paramTypes[i].getSimpleName().equals("Integer[]") ||
                            paramTypes[i].getSimpleName().equals("int[]") ||
                            paramTypes[i].getSimpleName().equals("String[]")) {
                        // 处理数组类型
                        args[i] = JSON.parseArray(value.toString(), paramTypes[i].getComponentType()).toArray();
                    } else if (paramTypes[i].isArray()) {
                        // 泛型数组处理
                        args[i] = JSON.parseArray(value.toString(), paramTypes[i].getComponentType()).toArray();
                    } else if (Map.class.isAssignableFrom(paramTypes[i])) {
                        // Map 类型
                        args[i] = JSON.parseObject(value.toString(), new TypeReference<Map<String, Object>>() {});
                    } else if (List.class.isAssignableFrom(paramTypes[i])) {
                        // List 类型
                        args[i] = JSON.parseObject(value.toString(), new TypeReference<List<?>>() {});
                    } else {
                        // 自定义对象类型
                        try {
                            args[i] = JSON.parseObject(value.toString(), paramTypes[i]);
                        } catch (JSONException e) {
                            throw new JSONException("JSON字符串类型错误: " + paramTypes[i], e);
                        }
                    }
                }

                method.setAccessible(true); // 如果是私有方法需要开启访问权限
                Object result = method.invoke(bean, args);
                return ResponseEntity.ok(result);
            }
        }

        return ResponseEntity.badRequest().body("找不到匹配的方法");
    }

}